<template>
  <div class="info-base">
    <div class="item-avatar">
      <div class="avatar">
        <img :src="userForm.data.avatar !== null ? userForm.data.avatar : defaultAvatar" alt="用户头像">
        <input type="file" class="fileinput" accept="image/gif,image/jpeg,image/jpg,image/png" @change="uploadAvatar">
      </div>
      <a href="javascript:;" class="text">点击头像修改</a>
    </div>
    <div class="item-name">
      <div class="label">昵称：</div>
      <div class="content">
        <input type="text" v-model="userForm.data.nickname" placeholder="请输入用户名">
      </div>
    </div>
    <div class="item-sex">
      <div class="label">性别：</div>
      <div class="content">
        <label for="item-sex-01">
          <input type="radio" name="item-sex" v-model="userForm.data.gender" value="男" id="item-sex-01" checked>
          <i class="radio"></i>
          <span>男</span>
        </label>
        <label for="item-sex-02">
          <input type="radio" name="item-sex" v-model="userForm.data.gender" value="女" id="item-sex-02">
          <i class="radio"></i>
          <span>女</span>
        </label>
        <label for="item-sex-03">
          <input type="radio" name="item-sex" v-model="userForm.data.gender" value="未知" id="item-sex-03">
          <i class="radio"></i>
          <span>未知</span>
        </label>
      </div>
    </div>
    <!-- 生日 -->
    <div class="item-birthday">
      <div class="label">生日：</div>
      <div class="content">
        <XtxDate v-model="userForm.data.birthday"></XtxDate>
      </div>
    </div>
    <!-- 城市 -->
    <div class="item-city">
      <div class="label">城市：</div>
      <div class="content">
        <XtxCity @change="changeCity" :fullLocation="userForm.data.fullLocation" />
      </div>
    </div>
    <!-- 职业 -->
    <div class="item-job">
      <div class="label">职业：</div>
      <div class="content">
        <xtx-select :options="jobOptions" v-model="userForm.data.profession"></xtx-select>
      </div>
    </div>
    <div class="item-btn">
      <div class="label"></div>
      <div class="content">
        <a href="javascript:;" class="save-btn" @click="save">保存</a>
      </div>
    </div>
  </div>
</template>

<script>
import { onMounted, reactive, ref } from 'vue'
import XtxDate from '@/components/library/xtx-date.vue'
import { jobs } from '@/api/constant'
import { findPersonalInfo, updatePersonalInfo, updateAvatar } from '@/api/personal'
import Message from '@/components/library/message'
export default {
  name: 'PersonalBaseInfo',
  components: {
    XtxDate
  },
  setup () {
    const defaultAvatar = require('@/assets/images/default_avatar.png')
    const jobOptions = jobs
    onMounted(() => {
      getUserProfile()
    })
    // 响应的结果赋值给我们页面上需要展示或者操作的变量,vue3中reactive数据被重新赋值后无法双向绑定，使用reactive包裹一个对象再赋值
    const userForm = reactive({
      data: {
        nickname: '',
        avatar: '',
        gender: '',
        birthday: '',
        provinceCode: '',
        cityCode: '',
        countyCode: '',
        fullLocation: '',
        profession: ''
      }
    })
    // 旧的用户信息对象，用于比对修改前后数据
    const oldUserForm = reactive({
      data: {}
    })
    // 头像更新
    const uploadAvatar = async (e) => {
      const $target = e.target || e.srcElement // ie下支持e.srcElement，ff支持e.target
      const file = $target.files[0] // 取第一张图
      const reader = new FileReader() // 允许Web应用程序异步读取存储在用户计算机上的文件
      // FileReader对象的readAsDataURL方法可以将读取到的文件编码成Data URL
      reader.readAsDataURL(file)
      // onload事件在页面或图像加载完成后的回调
      reader.onload = (data) => {
        const res = data.target || data.srcElement
        userForm.data.avatar = res.result
      }
      const formData = new FormData()
      formData.append('file', file)
      await updateAvatar(formData).then(data => {
        Message({ type: 'success', text: '头像更新成功' })
      })
    }
    // 获取用户信息
    const getUserProfile = () => {
      findPersonalInfo().then(data => {
        userForm.data = data.result
        // 取出参数对象的所有可遍历属性，并将其复制到旧用户信息对象之中
        oldUserForm.data = { ...userForm.data }
      })
    }
    // 城市选中事件处理函数
    const changeCity = (result) => {
      userForm.data.provinceCode = result.provinceCode
      userForm.data.cityCode = result.cityCode
      userForm.data.countyCode = result.countyCode
      userForm.data.fullLocation = result.fullLocation
    }
    const save = async () => {
      const form = { ...userForm.data }
      await updatePersonalInfo(form).then(data => {
        getUserProfile()
        oldUserForm.data = { ...userForm.data }
        Message({ type: 'success', text: '用户信息更新成功' })
      })
    }
    const infoHasUpdated = () => {
      // 是否已完成更新，false为否，true为是
      const hasUpdated = ref(false)
      // 遍历当前双向绑定的用户信息，如果当前用户信息有跟旧的信息不匹配，则说明信息有更改
      for (const key in userForm.data) {
        if (userForm.data[key] !== oldUserForm.data[key]) {
          // 有信息不匹配，则中断
          hasUpdated.value = true
          break
        }
      }
      return hasUpdated.value
    }
    return { userForm, oldUserForm, jobOptions, defaultAvatar, changeCity, uploadAvatar, save, infoHasUpdated }
  }
}
</script>

<style lang="less" scoped>
.info-base {
  padding: 20px;
  min-height: 400px;
  position: relative;
  .item-avatar {
    padding: 90px 0;
    display: block;
    .avatar {
      width: 106px;
      height: 106px;
      border-radius: 50%;
      overflow: hidden;
      margin: 0 auto;
      position: relative;
      img {
        max-width: 100%;
        max-height: 100%;
        vertical-align: middle;
      }
      input {
        width: 106px;
        height: 106px;
        position: absolute;
        left: 0;
        top: 0;
        opacity: 0;
      }
    }
    .text {
      display: block;
      text-align: center;
      padding-top: 24px;
      color: #27ba9b;
    }
  }
  .item-name {
    display: flex;
    padding-bottom: 20px;
    .label {
      width: 340px;
      padding-right: 20px;
      text-align: right;
      font-size: 16px;
      color: #999;
      line-height: 50px;
    }
    .content {
      width: 300px;
      height: 50px;
      line-height: 50px;
      input {
        border: 1px solid #e4e4e4;
        width: 100%;
        height: 100%;
        padding: 0 10px;
      }
    }
  }
  .item-sex {
    display: flex;
    padding-bottom: 20px;
    .label {
      width: 340px;
      padding-right: 20px;
      text-align: right;
      font-size: 16px;
      color: #999;
      line-height: 50px;
    }
    .content {
      width: 300px;
      height: 50px;
      line-height: 50px;
      label {
        margin-right: 20px;
        position: relative;
        input {
          visibility: hidden;
          &:checked~ .radio {
            border-color: #27ba9b;
          }
          &:checked~ .radio::before {
            content: "";
            width: 7px;
            height: 7px;
            background: #27ba9b;
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%,-50%);
            border-radius: 50%;
          }
        }
        .radio {
          width: 14px;
          height: 14px;
          border: 1px solid #979797;
          border-radius: 50%;
          position: absolute;
          left: 0;
          top: 2px;
        }
        span {
          padding-left: 5px;
        }
      }
    }
  }
  .item-birthday {
    display: flex;
    padding-bottom: 20px;
    .label {
      width: 340px;
      padding-right: 20px;
      text-align: right;
      font-size: 16px;
      color: #999;
      line-height: 50px;
    }
    .content {
      width: 300px;
      height: 50px;
      line-height: 50px;
    }
  }
  .item-city {
    display: flex;
    padding-bottom: 20px;
    .label {
      width: 340px;
      padding-right: 20px;
      text-align: right;
      font-size: 16px;
      color: #999;
      line-height: 50px;
    }
    .content {
      width: 300px;
      height: 50px;
      line-height: 50px;
      .xtx-city {
        width: 300px;
        :deep(.select) {
          height: 50px;
          line-height: 48px;
          display: flex;
          padding: 0 10px;
          justify-content: space-between;
          .placeholder {
            color: #ccc;
          }
          i {
            color: #ccc;
            font-size: 18px;
          }
          .value {
            font-size: 14px;
          }
        }
        :deep(.option) {
          top: 49px;
        }
      }
    }
  }
  .item-job {
    display: flex;
    padding-bottom: 20px;
    .label {
      width: 340px;
      padding-right: 20px;
      text-align: right;
      font-size: 16px;
      color: #999;
      line-height: 50px;
    }
    .content {
      width: 300px;
      height: 50px;
      line-height: 50px;
    }
  }
  .item-btn {
    display: flex;
    padding: 60px 0;
    .label {
      width: 340px;
      padding-right: 20px;
      text-align: right;
      font-size: 16px;
      color: #999;
      line-height: 50px;
    }
    .content {
      width: 300px;
      height: 50px;
      line-height: 50px;
      .save-btn {
        width: 300px;
        line-height: 60px;
        height: 60px;
        background: #27ba9b;
        font-size: 16px;
        color: #fff;
        text-align: center;
        border-radius: 4px;
        display: inline-block;
      }
    }
  }
}
</style>
